package com.xbongbong.paas.help.menu;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.admin.pojo.vo.MirrorRollBackVO;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.dao.PaasPrintTemplateDao;
import com.xbongbong.paas.domain.entity.BusinessRuleInfoEntity;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.PaasPrintTemplateEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.BIProductEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.LowCodeHelp;
import com.xbongbong.paas.manager.feign.MirrorFeignClent;
import com.xbongbong.paas.model.BusinessRuleInfoModel;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.dto.ApplicationAddDTO;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.pojo.dto.FormEntityUpdateDTO;
import com.xbongbong.paas.pojo.dto.FormExplainAddDTO;
import com.xbongbong.paas.pojo.dto.MenuFormAddDTO;
import com.xbongbong.paas.pojo.dto.MenuGroupAddDTO;
import com.xbongbong.paas.service.CompanyConfigService;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.service.WorkReportSetService;
import com.xbongbong.paas.service.init.AbstractInitMenuHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.app.pojo.dto.ApplicationAddBatchDTO;
import com.xbongbong.pro.app.pojo.vo.ApplicationAddBatchVO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.enums.AccessLinkEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.WorkReportEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.CRMMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.form.pojo.dto.FormAddBatchDTO;
import com.xbongbong.pro.form.pojo.dto.FormUpdateBatchDTO;
import com.xbongbong.pro.form.pojo.vo.FormAddBatchVO;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainAddBatchDTO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainAddBatchVO;
import com.xbongbong.pro.fundset.pojo.FundSetTransitionPojo;
import com.xbongbong.pro.menu.pojo.dto.MenuFormAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuGroupAddBatchDTO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuGroupAddBatchVO;
import com.xbongbong.pro.menu.pojo.vo.MenuInitVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkReportSetEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.MirrorModuleEnum;
import com.xbongbong.saas.enums.PrintTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.WorkReportTypeEnum;
import com.xbongbong.saas.help.LabelHelp;
import com.xbongbong.saas.model.WorkReportSetModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.service.StageInitService;
import com.xbongbong.sys.domain.entity.MirrorCompanyEntity;
import com.xbongbong.sys.domain.entity.MirrorInfoEntity;
import com.xbongbong.sys.domain.entity.MirrorVersionEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.MirrorCompanyModel;
import com.xbongbong.sys.model.MirrorInfoModel;
import com.xbongbong.sys.model.MirrorVersionModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 *
 * @author 吴峰
 * @version v1.0
 * @date 2019/1/17 19:46
 * @since v1.0crm应用生成和菜单初始化
 */
@Component
public class InitCrmMenuHelp extends AbstractInitMenuHelp {

    private static final Logger LOG = LoggerFactory.getLogger(InitCrmMenuHelp.class);

    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private InitMenuHelp initMenuHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private CompanyConfigService companyConfigService;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasPrintTemplateDao paasPrintTemplateDao;
    @Resource
    private MirrorFeignClent mirrorFeignClent;
    @Resource
    private BusinessRuleInfoModel businessRuleInfoModel;
    @Resource
    private LabelHelp labelHelp;
    @Resource
    private StageInitService stageInitService;
    @Resource
    private LowCodeHelp lowCodeHelp;
    @Resource
    private InitProductMenuHelp initProductMenuHelp;
    @Resource
    private InitFundManagementMenuHelp initFundManagementMenuHelp;
    @Resource
    private WorkReportSetModel workReportSetModel;
    @Resource
    private WorkReportSetService workReportSetService;
    @Resource
    private MirrorVersionModel mirrorVersionModel;
    @Resource
    private MirrorCompanyModel mirrorCompanyModel;
    @Resource
    private MirrorInfoModel mirrorInfoModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private CommonHelp commonHelp;



    @Override
    public List<String> alias() {
        return Arrays.asList(SystemAppMenuEnum.CRM.getAlias());
    }

    @Override
    public MenuInitVO initApp(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        MenuInitVO productMenuInitVo = initProductMenuHelp.initMenu(menuInitDTO, appMap);
        if(Objects.isNull(productMenuInitVo)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        PaasFormEntity paasFormEntity = productMenuInitVo.getFormList().get(0);
        menuInitDTO.setProductForm(paasFormEntity);
        MenuInitVO crmMenuInitVO = initMenu(menuInitDTO, appMap);
        if(Objects.isNull(crmMenuInitVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        MenuInitVO fundManagement = initFundManagementMenuHelp.initMenu(menuInitDTO, appMap);
        if(Objects.isNull(fundManagement)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        List<PaasFormEntity> formList = crmMenuInitVO.getFormList();
        formList.addAll(productMenuInitVo.getFormList());
        formList.addAll(fundManagement.getFormList());
        crmMenuInitVO.setFormList(formList);
        // 插入CRM默认打印模板
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),formList,menuInitDTO.getAlias(), DistributorMarkEnum.OTHER.getCode());
        //插入资金管理默认打印模板
        initDefaultPrintTemplates(menuInitDTO.getCorpid(),fundManagement.getFormList(),XbbRefTypeEnum.FUND_MANAGEMENT.getAlias(), DistributorMarkEnum.OTHER.getCode());
        initQuickAndCommon(menuInitDTO);
        // 初始化管理中心--其他设置
        initOtherSet(menuInitDTO);
        //初始化资金账户
        initFundAccount(menuInitDTO, false);
        // 开启工作流
        commonHelp.openWorkflow(menuInitDTO.getCorpid());
        return crmMenuInitVO;
    }
    /**
     * CRM 简化版 - 初始化应用、菜单、表单、表单解释
     *
     * @param menuInitDTO
     * @return
     * @author xingxing.xiao
     * @date 2019/11/26 14:17
     */
    @Transactional(rollbackFor = Exception.class)
    public void simpleCrmInit(MenuInitDTO menuInitDTO) throws XbbException {
        String corpid = menuInitDTO.getCorpid();
        String userId = menuInitDTO.getUserId();
        try {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", "0");
            param.put("del", 0);
            // 1. 查询当前可用镜像版本
            MirrorVersionEntity mirrorVersion = mirrorVersionModel.getMirrorVersion(param);
            Long versionId = mirrorVersion.getId();
            // 2. 记录公司使用的镜像版本(初始化时随机选取公司使用镜像)
            MirrorCompanyEntity mirrorCompany = new MirrorCompanyEntity(corpid, versionId, userId);
            mirrorCompanyModel.insert(mirrorCompany);
            // 3. 查询该版本的镜像内容
            param.clear();
            param.put("columns", "id, module, info");
            param.put("versionId", versionId);
            param.put("moduleIn", Arrays.asList(MirrorModuleEnum.APP.getAlias(), MirrorModuleEnum.MENU.getAlias(), MirrorModuleEnum.FORM.getAlias(), MirrorModuleEnum.FIELD.getAlias()));
            List<MirrorInfoEntity> mirrorInfoList = mirrorInfoModel.findEntitys(param);
            // 4. 将 mirrorInfoList 转为 json, 方便后面按需取用
            JSONObject mirrorObj = new JSONObject();
            for (MirrorInfoEntity entity : mirrorInfoList) {
                mirrorObj.put(entity.getModule(), entity.getInfo());
            }

            // 创建应用
            JSONObject appObj = mirrorObj.getJSONObject(MirrorModuleEnum.APP.getAlias());
            if (StringUtil.isEmpty(appObj.toString())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            menuInitDTO = addSimpleApp(menuInitDTO, appObj);
            // 3. 处理产品 - 创建菜单、表单、表单解释
            MenuInitVO productMenuInitVo =  initProductMenuHelp.initSimpleMenu(menuInitDTO, mirrorObj);
            if(Objects.isNull(productMenuInitVo)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            PaasFormEntity paasFormEntity = productMenuInitVo.getFormList().get(0);
            menuInitDTO.setProductForm(paasFormEntity);
            // 1. 处理CRM - 创建菜单、表单、表单解释
            MenuInitVO crmMenuInitVO = initSimpleMenu(menuInitDTO, mirrorObj);
            if(Objects.isNull(crmMenuInitVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            // 2. 处理资金管理 - 创建菜单、表单、表单解释
            MenuInitVO fundManagement = initFundManagementMenuHelp.initSimpleMenu(menuInitDTO, mirrorObj);
            if(Objects.isNull(fundManagement)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }


            List<PaasFormEntity> formList = crmMenuInitVO.getFormList();
            formList.addAll(productMenuInitVo.getFormList());
            formList.addAll(fundManagement.getFormList());
            crmMenuInitVO.setFormList(formList);
            // 插入CRM默认打印模板
            initDefaultPrintTemplates(menuInitDTO.getCorpid(),formList,menuInitDTO.getAlias(), DistributorMarkEnum.OTHER.getCode());
            //插入资金管理默认打印模板
            initDefaultPrintTemplates(menuInitDTO.getCorpid(),fundManagement.getFormList(),XbbRefTypeEnum.FUND_MANAGEMENT.getAlias(), DistributorMarkEnum.OTHER.getCode());
            // 初始化快捷新建和常用表单
            initQuickAndCommon(menuInitDTO);
            // 初始化管理中心--其他设置
            initOtherSet(menuInitDTO);
        } catch (XbbException e){
            LOG.error("MenuInitHelp.simpleCrmInit初始化菜单出错", e);
            throw e;
        } catch (Exception e){
            LOG.error("MenuInitHelp.simpleCrmInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * CRM简化版-初始化应用
     * @param menuInitDTO
     * @param appObj 应用镜像
     * @author xingxing.xiao
     * @date 2019/11/28 16:01
     */
    private MenuInitDTO addSimpleApp(MenuInitDTO menuInitDTO, JSONObject appObj) throws XbbException {
        try {
            Map<String, PaasAppEntity> appMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            JSONArray aliasArray = appObj.getJSONArray("alias");
            // 校验应用是否已开通
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", menuInitDTO.getCorpid());
            List<String> aliasList = JSONObject.parseArray(aliasArray.toJSONString(), String.class);
            param.put("aliasIn", aliasList);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasAppEntity> appList = paasAppModel.findEntitys(param);
            if(Objects.isNull(appList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            appList.forEach((item)->{
                appMap.put(item.getAlias(), item);
            });
            // 准备批量插入
            ApplicationAddBatchDTO applicationAddBatchDTO = new ApplicationAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, applicationAddBatchDTO);
            List<ApplicationAddDTO> insertAppList = new ArrayList<>();
            ApplicationAddDTO applicationAddDTO = new ApplicationAddDTO();
            BeanUtil.copyProperties(menuInitDTO, applicationAddDTO);

            // CRM
            if (!appMap.containsKey(SystemAppMenuEnum.CRM.getAlias())) {
                SystemAppMenuEnum systemAppMenuEnum = SystemAppMenuEnum.getSystemAppMenuEnum(SystemAppMenuEnum.CRM.getAlias());
                AccessLinkEnum accessLinkEnum = systemAppMenuEnum.getAccessLinkEnum();
                applicationAddDTO.setIcon(accessLinkEnum.getIcon());
                applicationAddDTO.setColor(accessLinkEnum.getColor());
                applicationAddDTO.setName(systemAppMenuEnum.getName());
                insertAppList.add(applicationAddDTO);
            }
            // 资金管理
            if (!appMap.containsKey(SystemAppMenuEnum.FUND_MANAGEMENT.getAlias())) {
                ApplicationAddDTO fundManagement = getFundManagement(menuInitDTO);
                if (!aliasArray.contains(SystemAppMenuEnum.FUND_MANAGEMENT.getAlias())) {
                    fundManagement.setEnable(BasicConstant.NO_USE);
                }
                insertAppList.add(fundManagement);
            }
            // 产品
            if (!appMap.containsKey(SystemAppMenuEnum.PRODUCT.getAlias())) {
                ApplicationAddDTO productApp = getProductApp(menuInitDTO);
                if (!aliasArray.contains(SystemAppMenuEnum.PRODUCT.getAlias())) {
                    productApp.setEnable(BasicConstant.NO_USE);
                }
                insertAppList.add(productApp);
            }
            // 市场管理
            if (!appMap.containsKey(SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias())) {
                ApplicationAddDTO productApp = getInsertApp(menuInitDTO, SystemAppMenuEnum.MARKET_MANAGEMENT, 0);
                if (!aliasArray.contains(SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias())) {
                    productApp.setEnable(BasicConstant.NO_USE);
                }
                insertAppList.add(productApp);
            }

            applicationAddBatchDTO.setAppList(insertAppList);
            ApplicationAddBatchVO applicationAddBatchVO = paasAppService.addBatchPaasApp(applicationAddBatchDTO);
            if (Objects.isNull(applicationAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<PaasAppEntity> resultList = applicationAddBatchVO.getAppList();
            resultList.forEach((item)->{
                appMap.put(item.getAlias(), item);
            });
            menuInitDTO.setAppMap(appMap);
        } catch (XbbException e) {
            LOG.error("MenuInitHelp.addSimpleApp初始化应用出错", e);
            throw e;
        } catch (Exception e) {
            LOG.error("MenuInitHelp.addSimpleApp初始化应用出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitDTO;
    }




    /**
     * 初始化其他设置：工作报告设置
     *
     * @param * @param null
     * @throws
     * @return
     * @author hongxiao
     * @date 2019-11-14 10:12
     * @since
     * @version
     */
    private void initOtherSet(MenuInitDTO menuInitDTO) throws XbbException {
        // 初始化工作报告设置
        List<Integer> allList = new ArrayList<>();
        allList.add(WorkReportTypeEnum.DAILY.getType());
        allList.add(WorkReportTypeEnum.WEEKLY.getType());
        allList.add(WorkReportTypeEnum.MONTHLY.getType());

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("typeIn", allList);
        param.put(StringConstant.CORPID, menuInitDTO.getCorpid());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> list = workReportSetModel.findEntitys(param);
        List<Integer> dbTypeList = new ArrayList<>();
        if(Objects.nonNull(list) && !list.isEmpty()) {
            for (WorkReportSetEntity entity : list) {
                dbTypeList.add(entity.getType());
            }
        }
        allList.removeAll(dbTypeList);
        if(!allList.isEmpty()) {
            for (Integer type : allList) {
                workReportSetService.initSetting(menuInitDTO.getCorpid(), menuInitDTO.getUserId(), type);
            }
        }

    }

    /**
     * crm菜单初始化
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @return void
     * @throws XbbException
     */
    @Override
    public MenuInitVO initMenu(MenuInitDTO menuInitDTO, Map<String, PaasAppEntity> appMap) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            // 获取下应用id
            Long appId = appMap.get(SystemAppMenuEnum.CRM.getAlias()).getId();
            menuInitDTO.setAppId(appId);
            // 插入菜单分组
            MenuGroupAddBatchVO crmGroupAddBatchVO = groupAddBatch(menuInitDTO);
            if(Objects.isNull(crmGroupAddBatchVO)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入除分组外对应的菜单
            MenuFormAddBatchVO menuFormAddBatchVO = formAddBatch(menuInitDTO, crmGroupAddBatchVO);
            if (Objects.isNull(menuFormAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<PaasMenuEntity> menuGroupList = crmGroupAddBatchVO.getMenuList();
            List<PaasMenuEntity> menuFormList = menuFormAddBatchVO.getMenuList();
            List<PaasMenuEntity> menuList = new ArrayList<>();
            menuList.addAll(menuGroupList);
            menuList.addAll(menuFormList);
            // 插入菜单对应的表单
            FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
            List<FormEntityAddDTO> formList = new ArrayList<>();
            // 通过分组菜单，得到需要插入的表单列表
            getFormList(formList, menuList);
            //添加跟进记录的form
            setContractPerformance(appId, formList,menuInitDTO.getCorpid(),menuInitDTO.getUserId());
            formAddBatchDTO.setFormList(formList);
            FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
            if (Objects.isNull(formAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 插入表单对应的字段解释
            formExplainAddBatch(menuInitDTO, formAddBatchVO);
            menuInitVO.setFormList(formAddBatchVO.getFormList());
            // 新公司初始化时，默认开启钉钉待办(enable = 1)
            dingtalkWorkrecordConfig(menuInitDTO.getCorpid());
            // 客户、机会表单需要初始化阶段
            formAddBatchVO.getFormList().forEach(form -> {
                Integer businessType = form.getBusinessType();
                boolean needInitStage = Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) ||
                        Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), businessType);
                if (needInitStage) {
                    stageInitService.init(form.getCorpid(), businessType, form.getId());
                }
            });
            // 插入项目决策信息表单
            setDecisionInfoFormAndExplain(appId, menuInitDTO.getCorpid(), menuInitDTO.getUserId());
            setCompetitorAnalysisFormAndExplain(appId, menuInitDTO.getCorpid(), menuInitDTO.getUserId());
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    /**
     * 回退 CRM 表单到初始化
     * @param mirrorRollBackDTO
     * @param systemFormList 安装的系统表单
     * @param paasProductFormEntity
     * @throws XbbException
     * @author guohui.zhang
     */
    @Override
    public void rollBackInit(MirrorRollBackDTO mirrorRollBackDTO, List<Long> systemFormList, PaasFormEntity paasProductFormEntity) throws XbbException {
        String targetCorpid = mirrorRollBackDTO.getTargetCorpid();
        Long appId = mirrorRollBackDTO.getAppId();
        try {
            // 1. 根据安装的系统表单反推菜单
            HashSet<Long> menuIds = new HashSet<>();
            HashMap<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("idIn", systemFormList);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormEntity> sysInstallFormList = paasFormModel.findEntity(param);
            sysInstallFormList.forEach(item -> {
                menuIds.add(item.getMenuId());
            });
            // 2. 根据菜单找所有表单
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("menuIdIn", menuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasFormEntity> paasFormList = paasFormModel.findEntity(param);
            HashSet<Long> formIds = new HashSet<>();
            paasFormList.forEach(item -> {
                formIds.add(item.getId());
            });
            // 校验是否有数据
            newCheckData(mirrorRollBackDTO);

            // 3. 回退菜单
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("idOrParentIdIn", menuIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasMenuEntity> paasMenuList = paasMenuModel.findEntitys(param);
            updateInitMenu(paasMenuList, targetCorpid);

            // 4. 回退表单
            List<FormEntityUpdateDTO> formList = new ArrayList<>();
            HashMap<Long,PaasFormEntity> systemPaasForms =new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            PaasFormEntity retainPaasFormEntity = new PaasFormEntity();
            List<Long> delFormIds = new ArrayList<>();
            Integer customNum = 0;
            Integer contract = 0;
            Integer saleOpportunity = 0;
            for (PaasFormEntity paasFormEntity : paasFormList) {
                FormEntityUpdateDTO formEntityUpdateDTO = new FormEntityUpdateDTO();
                //客户可能会有删除操作,增加操作
                // 处理客户
                if (Objects.equals(paasFormEntity.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    if (customNum == 0) {
                        paasFormEntity.setName(I18nMessageUtil.getMessage(BusinessConstant.COMPANY_CUSTOMER_NAME));
                        BeanUtil.copyProperties(paasFormEntity,retainPaasFormEntity);
                        customNum++;
                    } else if (customNum == 1) {
                        paasFormEntity.setName(I18nMessageUtil.getMessage(BusinessConstant.PERSONAL_CUSTOMER_NAME));
                        customNum++;
                    } else {
                        paasFormEntity.setDel(DelEnum.DELETE.getDel());
                        delFormIds.add(paasFormEntity.getId());
                        customNum++;
                    }
                } else if (Objects.equals(paasFormEntity.getBusinessType(), XbbRefTypeEnum.CONTRACT.getCode())) {
                    // 合同只会有删除操作
                    if (contract == 0) {
                        contract++;
                    } else {
                        paasFormEntity.setDel(DelEnum.DELETE.getDel());
                        delFormIds.add(paasFormEntity.getId());
                        contract++;
                    }
                } else if (Objects.equals(paasFormEntity.getBusinessType(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())) {
                    // 销售机会只会有删除操作
                    if (saleOpportunity == 0) {
                        saleOpportunity++;
                    } else {
                        paasFormEntity.setDel(DelEnum.DELETE.getDel());
                        delFormIds.add(paasFormEntity.getId());
                        saleOpportunity++;
                    }
                }
                BeanUtil.copyProperties(paasFormEntity, formEntityUpdateDTO);
                formList.add(formEntityUpdateDTO);
                systemPaasForms.put(paasFormEntity.getId(), paasFormEntity);
            }
            // 更新表单到初始化
            getUpdateFormList(formList);
            FormUpdateBatchDTO formUpdateBatchDTO = new FormUpdateBatchDTO();
            formUpdateBatchDTO.setCorpid(targetCorpid);
            formUpdateBatchDTO.setFormList(formList);
            formUpdateBatchDTO.setCompanyInit(1);
            // 回退表单
            paasFormService.updateBatch4Mirror(formUpdateBatchDTO);
            UserEntity userEntity = new UserEntity();
            userEntity.setCorpid(targetCorpid);
            userEntity.setUserId("");
            userEntity.setName("");
            if (customNum == 1){
                // 如果缺少个人客户模板,新加个人客户表单及解释
                PaasFormEntity paasFormEntity = new PaasFormEntity();
                BeanUtil.copyProperties(retainPaasFormEntity, paasFormEntity);
                paasFormEntity.setName(I18nMessageUtil.getMessage(BusinessConstant.PERSONAL_CUSTOMER_NAME));
                paasFormEntity.setCreatorId(userEntity.getUserId());
                paasFormEntity.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                paasFormEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormEntity.setLabels(JSONObject.toJSONString(getAppDefaultLabel(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())));
                paasFormEntity.setCustomTitle(JSONObject.toJSONString(getAppDefaultTitle(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())));
                paasFormEntity.setSummary(JSONObject.toJSONString(getAppDefaultSummary(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())));
                paasFormEntity.setEnable(BasicConstant.ONE);
                paasFormEntity.setBusinessRules("0");
                paasFormModel.insert(paasFormEntity);
                PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
                String alias = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getAlias();
                List<FieldAttrEntity> explainList ;
                FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(targetCorpid);
                explainList=InitExplainsHelper.initFieldAttrEntity(alias,paasProductFormEntity,fundSetTransitionPojo, 0);
                removePersonalCustomerField(explainList);
                paasFormExplainEntity.setExplains(JSONObject.toJSONString(explainList));
                paasFormExplainEntity.setDel(DelEnum.NORMAL.getDel());
                long now = DateTimeUtil.getInt();
                paasFormExplainEntity.setAddTime(now);
                paasFormExplainEntity.setUpdateTime(now);
                paasFormExplainEntity.setEnable(BasicConstant.ONE);
                paasFormExplainEntity.setBusinessType(paasFormEntity.getBusinessType());
                paasFormExplainEntity.setCreatorId(userEntity.getUserId());
                paasFormExplainEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormExplainEntity.setFormId(paasFormEntity.getId());
                paasFormExplainEntity.setCorpid(paasFormEntity.getCorpid());
                paasFormExplainEntity.setMenuId(paasFormEntity.getMenuId());
                paasFormExplainEntity.setAppId(paasFormEntity.getAppId());
                paasFormExplainModel.insert(paasFormExplainEntity);
            }

            // 3. 表单解释
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("formIdIn", formIds);
            param.put("saasMark", SaasMarkEnum.SAAS.getCode());
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
            formExplainUpdateBatch(paasProductFormEntity, paasFormExplainEntityList, mirrorRollBackDTO.getTargetCorpid(),systemPaasForms,delFormIds);

            /*// 更新应用信息(待定)
            PaasAppEntity paasAppEntity = paasAppModel.getByKey(mirrorRollBackDTO.getAppId(), mirrorRollBackDTO.getTargetCorpid());
            SystemAppMenuEnum systemAppMenuEnum = SystemAppMenuEnum.getSystemAppMenuEnum(mirrorRollBackDTO.getAlias());
            AccessLinkEnum accessLinkEnum = systemAppMenuEnum.getAccessLinkEnum();
            paasAppEntity.setIcon(accessLinkEnum.getIcon());
            paasAppEntity.setColor(accessLinkEnum.getColor());
            paasAppEntity.setName(systemAppMenuEnum.getName());
            paasAppModel.update(paasAppEntity);*/

            //更新打印模板
            rollBackToDefaultPrintTemplates(targetCorpid,appId,paasFormList,mirrorRollBackDTO.getAlias(),delFormIds);

            // 初始化时是没有业务规则的，所以删除表单对应的所有业务规则
            param.clear();
            param.put("corpid", targetCorpid);
            param.put("appId", appId);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("formIdIn", formIds);
            param.put("saasMark", SaasMarkEnum.SAAS.getCode());
            List<BusinessRuleInfoEntity> ruleInfoEntityList = businessRuleInfoModel.findEntitys(param);
            Set<Long> ruleIdSets = new HashSet<>();
            ruleInfoEntityList.forEach(item -> ruleIdSets.add(item.getId()));
            List<Long> ruleIdIn = new ArrayList<>(ruleIdSets);
            if (ruleIdIn.size() > 0) {
                businessRuleInfoModel.deleteBatch(ruleIdIn, targetCorpid);
            }
            // 标签初始化
            labelHelp.deleteAllAndinit(paasFormList, targetCorpid, appId);

            // 初始化时没有低代码 此处删除所有低代码及配置
            lowCodeHelp.deleteLowCode(targetCorpid, formIds);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    public Boolean newCheckData(MirrorRollBackDTO mirrorRollBackDTO) throws XbbException{
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        XbbResponse<MirrorRollBackVO> mirrorRollBackVOXbbResponse = mirrorFeignClent.checkData(mirrorRollBackDTO, lang);
        if (mirrorRollBackVOXbbResponse.isSuccess()) {
            return true;
        } else {
            throw new XbbException(mirrorRollBackVOXbbResponse.getCode(), mirrorRollBackVOXbbResponse.getMsg());
        }
    }
    /**
     * 区分自定义表单和系统表单
     * @param menuIds
     * @param paasFormEntityExt
     * @return
     */
    private boolean validSystemOrustomForm(List<Long> menuIds, PaasFormEntityExt paasFormEntityExt) {
        return (menuIds.contains(paasFormEntityExt.getMenuId()) && Objects.equals(paasFormEntityExt.getSaasMark(),SaasMarkEnum.SAAS.getCode()))
                || (Objects.equals(paasFormEntityExt.getBusinessType(),XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode()))
                    ||  (Objects.nonNull(WorkReportEnum.getByCode(paasFormEntityExt.getBusinessType())));
    }

    /**
     * 更新表单到初始化
     * @param formList
     * @return
     * @throws XbbException
     */
    private List<FormEntityUpdateDTO> getUpdateFormList(List<FormEntityUpdateDTO> formList) throws XbbException{
        try {
            for (FormEntityUpdateDTO formEntityAddDTO : formList) {
                if (Objects.equals(formEntityAddDTO.getDel(),DelEnum.NORMAL.getDel())) {
                    CRMMenuEnum formEnum = CRMMenuEnum.getByCode(formEntityAddDTO.getBusinessType());
                    // 合同业绩分配暂不做处理
                    if (Objects.equals(XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode(),formEntityAddDTO.getBusinessType())){
                        continue;
                    }
                    if (Objects.nonNull(formEnum)){
                        // 排除客户和机会下子菜单，排除资金管理和签到，排除发票和回款
                        boolean result = StringUtil.isNotEmpty(formEnum.getParent())
                                || CRMMenuEnum.SIGN_IN.getCode().equals(formEntityAddDTO.getBusinessType());
                        if(result) {
                            continue;
                        }
                        if (!Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), formEnum.getCode())){
                            formEntityAddDTO.setName(formEnum.getName());
                        }
                        formEntityAddDTO.setCustomTitle(getAppDefaultTitle(formEnum.getCode()));
                        formEntityAddDTO.setLabels(getAppDefaultLabel(formEnum.getCode()));
                        formEntityAddDTO.setSummary(getAppDefaultSummary(formEnum.getCode()));
                        formEntityAddDTO.setBusinessRules("0");
                        formEntityAddDTO.setAssociationList(new ArrayList<>());
                        // 工作报告含有日报，周报，月报，需要修改三张表，对应菜单为工作报告
                        if (Objects.nonNull(WorkReportEnum.getByCode(formEntityAddDTO.getBusinessType()))){
                            formEntityAddDTO.setName(WorkReportEnum.getByCode(formEntityAddDTO.getBusinessType()).getName());
                        }
                        if (Objects.equals(formEntityAddDTO.getBusinessType(),XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())){
                            // formEntityAddDTO.setName(BusinessConstant.PERSONAL_CUSTOMER_NAME);
                            formEntityAddDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                            formEntityAddDTO.setLabels(getAppDefaultLabel(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
                            formEntityAddDTO.setCustomTitle(getAppDefaultTitle(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
                            formEntityAddDTO.setSummary(getAppDefaultSummary(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
                        }
                    }else if (Objects.nonNull(WorkReportEnum.getByCode(formEntityAddDTO.getBusinessType()))){
                        WorkReportEnum workReportEnum = WorkReportEnum.getByCode(formEntityAddDTO.getBusinessType());
                        formEntityAddDTO.setName(workReportEnum.getName());
                        formEntityAddDTO.setBusinessType(workReportEnum.getCode());
                        formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    } else {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                    }
                }
            }
        }catch (XbbException e) {
            throw e;
        }
        return formList;
    }

    /**
     * 回退到初始化解释
     * @param paasProductFormEntity
     * @param paasFormExplainEntityList
     * @param corpid
     * @param systemPaasForms
     * @return
     * @throws XbbException
     */
    public List<PaasFormExplainEntity> formExplainUpdateBatch(PaasFormEntity paasProductFormEntity,List<PaasFormExplainEntity> paasFormExplainEntityList ,String corpid,HashMap<Long, PaasFormEntity> systemPaasForms,List<Long> delFormIds) throws XbbException {
        try {
            FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(corpid);
            for (PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList) {
                if (delFormIds.contains(paasFormExplainEntity.getFormId())){
                    paasFormExplainEntity.setDel(DelEnum.DELETE.getDel());
                }else{
                    // 过滤掉bi的一些表单
                    BIProductEnum biProductEnum = BIProductEnum.getByCode(paasFormExplainEntity.getBusinessType());
                    if (Objects.nonNull(biProductEnum) ||
                            Objects.equals(paasFormExplainEntity.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                        continue;
                    }
                    String alias = XbbRefTypeEnum.getByCode(paasFormExplainEntity.getBusinessType()).getAlias();
                    List<FieldAttrEntity> fieldAttrEntities=new ArrayList<>();
                    CRMMenuEnum crmMenuEnum = CRMMenuEnum.getByAlias(alias);
                    if (Objects.nonNull(crmMenuEnum)){
                        if (StringUtil.isNotEmpty(crmMenuEnum.getParent())){
                            fieldAttrEntities=(InitExplainsHelper.initFieldAttrEntity(crmMenuEnum.getParent(),paasProductFormEntity,fundSetTransitionPojo, 0));
                        }else{
                            fieldAttrEntities=(InitExplainsHelper.initFieldAttrEntity(alias,paasProductFormEntity,fundSetTransitionPojo, 0));
                        }
                        if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), paasFormExplainEntity.getBusinessType())
                                && I18nMessageUtil.getMessage(BusinessConstant.COMPANY_CUSTOMER_NAME).equals(systemPaasForms.get(paasFormExplainEntity.getFormId()).getName())) {
                            removeCompanyCustomerField(fieldAttrEntities);
                        } else if ((Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), paasFormExplainEntity.getBusinessType()) && I18nMessageUtil.getMessage(BusinessConstant.PERSONAL_CUSTOMER_NAME).equals(systemPaasForms.get(paasFormExplainEntity.getFormId()).getName()))) {
                            removePersonalCustomerField(fieldAttrEntities);
                        }
                    }else if (Objects.nonNull(WorkReportEnum.getByCode(paasFormExplainEntity.getBusinessType()))){
                        WorkReportEnum workReportEnum = WorkReportEnum.getByCode(paasFormExplainEntity.getBusinessType());
                        InitExplainsHelper.initFieldAttrEntity(workReportEnum.getAlias(),paasProductFormEntity,fundSetTransitionPojo, 0);
                    }
                    paasFormExplainEntity.setExplains(JSON.toJSONString(fieldAttrEntities));
                }
            }
            paasFormExplainModel.updateBatch(paasFormExplainEntityList,corpid);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainUpdateBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return paasFormExplainEntityList;
    }

    /**
     * 修改菜单到初始化状态

     * @return
     * @throws XbbException
     */
    private void updateInitMenu(List<PaasMenuEntity> paasMenuEntites,String corpid) throws XbbException {
        try {
            for (PaasMenuEntity paasMenuEntite : paasMenuEntites) {
                CRMMenuEnum menuEnum = CRMMenuEnum.getByAlias(paasMenuEntite.getAlias());
                paasMenuEntite.setName(menuEnum.getName());
                AccessLinkEnum accessLinkEnum = menuEnum.getAccessLinkEnum();
                paasMenuEntite.setIcon(accessLinkEnum.getIcon());
                paasMenuEntite.setEnable(EnableEnum.OPEN.getCode());
                paasMenuEntite.setColor(accessLinkEnum.getColor());
                paasMenuEntite.setUrl(accessLinkEnum.getUrl());
                paasMenuEntite.setType(menuEnum.getType());
                paasMenuEntite.setMobileUrl(accessLinkEnum.getMobileUrl());
            }
            paasMenuModel.updateBatch(paasMenuEntites,corpid);
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.Upad", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 添加跟进记录的form
     * @param appId
     * @param formList
     */
    public void setContractPerformance(Long appId, List<FormEntityAddDTO> formList,String corpid,String creatorId) {
        FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
        formEntityAddDTO.setBusinessType(XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode());
        formEntityAddDTO.setAppId(appId);
        formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formEntityAddDTO.setName(XbbRefTypeEnum.CONTRACT_PERFORMANCE.getName());
        long now = DateUtil.getNow();
        formEntityAddDTO.setAddTime(now);
        formEntityAddDTO.setUpdateTime(now);
        formEntityAddDTO.setCorpid(corpid);
        formEntityAddDTO.setMenuId(0L);
        formEntityAddDTO.setCreatorId(creatorId);
        formList.add(formEntityAddDTO);
    }

    /**
     * 添加项目决策信息表单及解释（入口在联系人表单）
     * @param appId 应用id
     * @param corpid 公司id
     * @param creatorId　创建人id
     * @throws XbbException
     */
    public void setDecisionInfoFormAndExplain(Long appId, String corpid, String creatorId) throws XbbException {
        PaasFormEntity formEntity = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.PROJECT_DECISION_INFO.getCode(), corpid);
        if (Objects.nonNull(formEntity)) {
            return;
        }
        if (Objects.isNull(creatorId)) {
            creatorId = "0";
        }

        long now = DateUtil.getNow();
        formEntity = new PaasFormEntity(corpid, appId, 0L, XbbRefTypeEnum.PROJECT_DECISION_INFO.getName(), SaasMarkEnum.SAAS.getCode(),
                XbbRefTypeEnum.PROJECT_DECISION_INFO.getCode(), BasicConstant.IS_USE, 0, "", 1, 0, 2,
                "", "", "", "", null, null, "", "",
                "", "", creatorId, now, now, DelEnum.NORMAL.getDel(), null, 0, DistributorMarkEnum.OTHER.getCode());
        formEntity.setSort(0);
        paasFormModel.insert(formEntity);


        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        paasFormExplainEntity.setExplains("[]");
        paasFormExplainEntity.setDel(DelEnum.NORMAL.getDel());
        paasFormExplainEntity.setAddTime(now);
        paasFormExplainEntity.setUpdateTime(now);
        paasFormExplainEntity.setEnable(BasicConstant.ONE);
        paasFormExplainEntity.setBusinessType(formEntity.getBusinessType());
        paasFormExplainEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
        paasFormExplainEntity.setCreatorId(formEntity.getCreatorId());
        paasFormExplainEntity.setFormId(formEntity.getId());
        paasFormExplainEntity.setCorpid(corpid);
        paasFormExplainEntity.setMenuId(formEntity.getMenuId());
        paasFormExplainEntity.setAppId(formEntity.getAppId());
        paasFormExplainEntity.setDistributorMark(DistributorMarkEnum.OTHER.getCode());
        paasFormExplainModel.insert(paasFormExplainEntity);
    }

    /**
     * 添加表单字段解释
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param menuInitDTO
     * @param formAddBatchVO 表单数据
     * @return 返回表单字段对象
     * @throws XbbException
     */
    public FormExplainAddBatchVO formExplainAddBatch(MenuInitDTO menuInitDTO, FormAddBatchVO formAddBatchVO) throws XbbException {
        FormExplainAddBatchVO formExplainAddBatchVO;
        try {
            List<PaasFormEntity> formResultList = formAddBatchVO.getFormList();
            FormExplainAddBatchDTO formExplainAddBatchDTO = new FormExplainAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formExplainAddBatchDTO);
            List<FormExplainAddDTO> formExplainList = new ArrayList<>();
            FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(menuInitDTO.getCorpid());
            for (PaasFormEntity item : formResultList) {
                // 过滤掉bi的一些表单
                BIProductEnum biProductEnum = BIProductEnum.getByCode(item.getBusinessType());
                if (Objects.nonNull(biProductEnum) ||
                        Objects.equals(item.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                    continue;
                }
                FormExplainAddDTO formExplainAddDTO = new FormExplainAddDTO();
                BeanUtil.copyProperties(item, formExplainAddDTO);
                formExplainAddDTO.setFormId(item.getId());
                String alias = XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias();
                CRMMenuEnum crmMenuEnum = CRMMenuEnum.getByAlias(alias);
                // 初始化方法获取字段列表
                List<FieldAttrEntity> explainList = new ArrayList<>();
                if (!InitExplainsHelper.EMPTY_EXPLAIN.contains(item.getBusinessType())) {
                    if(Objects.nonNull(crmMenuEnum)) {
                        if(StringUtil.isNotEmpty(crmMenuEnum.getParent())){
                            explainList =InitExplainsHelper.initFieldAttrEntity(crmMenuEnum.getParent(),menuInitDTO.getProductForm(),fundSetTransitionPojo, 0);
                        } else {
                            explainList = InitExplainsHelper.initFieldAttrEntity(alias,menuInitDTO.getProductForm(),fundSetTransitionPojo, 0);
                        }
                        if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), item.getBusinessType())
                                && I18nMessageUtil.getMessage(BusinessConstant.COMPANY_CUSTOMER_NAME).equals(item.getName())) {
                            //explainList.addAll(InitExplainsHelper.initFieldAttrEntity(BusinessConstant.COMPANY_CUSTOMER_ALIAS));
                            removeCompanyCustomerField(explainList);
                        } else if ((Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), item.getBusinessType()) && I18nMessageUtil.getMessage(BusinessConstant.PERSONAL_CUSTOMER_NAME).equals(item.getName()))) {
                            //explainList.addAll(InitExplainsHelper.initFieldAttrEntity(BusinessConstant.PERSONAL_CUSTOMER_ALIAS));
                            removePersonalCustomerField(explainList);
                        }
                    } else {
                        WorkReportEnum workReportEnum = WorkReportEnum.getByCode(item.getBusinessType());
                        explainList = InitExplainsHelper.initFieldAttrEntity(workReportEnum.getAlias(),menuInitDTO.getProductForm(),fundSetTransitionPojo, 0);
                    }
                }
                formExplainAddDTO.setFormList(explainList);
                formExplainList.add(formExplainAddDTO);
               /* // 合同的其他费用
                if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), item.getBusinessType())){
                    surchargeModel.initSurcharge(item.getCorpid(), item.getId());
                }*/
            }
            formExplainAddBatchDTO.setFormExplainList(formExplainList);
            formExplainAddBatchVO = paasFormExplainService.addBatch(formExplainAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainAddBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainAddBatchVO;
    }

    /**
     * 企业客户，砍掉字段：客户生日
     * @param explainList
     */
    public void removeCompanyCustomerField(List<FieldAttrEntity> explainList) {
        Iterator<FieldAttrEntity> iterator = explainList.iterator();
        while (iterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = iterator.next();
            if (CustomerManagementEnum.BIRTHDAY.getAttr().equals(fieldAttrEntity.getAttr())
                    || CustomerManagementEnum.SEX.getAttr().equals(fieldAttrEntity.getAttr())
                    || CustomerManagementEnum.QQ.getAttr().equals(fieldAttrEntity.getAttr())
                    || CustomerManagementEnum.WE_CHRT.getAttr().equals(fieldAttrEntity.getAttr())
                    || CustomerManagementEnum.HOBBIES.getAttr().equals(fieldAttrEntity.getAttr())) {
                iterator.remove();
            }
        }
        Collections.sort(explainList, new Comparator<FieldAttrEntity>() {
            @Override
            public int compare(FieldAttrEntity o1, FieldAttrEntity o2) {
                //降序
                return o2.getSort() - o1.getSort();
            }
        });
    }

    /**
     * 个人客户，砍掉字段：客户简称、客户官网、以及主联系人的两个字段
     * @param explainList
     */
    public void removePersonalCustomerField(List<FieldAttrEntity> explainList) {
        Iterator<FieldAttrEntity> iterator = explainList.iterator();
        while (iterator.hasNext()) {
            FieldAttrEntity fieldAttrEntity = iterator.next();
            String attr = fieldAttrEntity.getAttr();
            if (CustomerManagementEnum.ADD_CONTACT.getAttr().equals(attr) || CustomerManagementEnum.ASSOCIATED_INFO.getAttr().equals(attr)) {
                fieldAttrEntity.setIsOpen(0);
            }
            if (CustomerManagementEnum.NAME_SHORT.getAttr().equals(attr)
                    || CustomerManagementEnum.WEBSITE.getAttr().equals(attr)
                    || CustomerManagementEnum.CONTACT_NAME.getAttr().equals(attr)
                    || CustomerManagementEnum.CONTACT_PHONE.getAttr().equals(attr)) {
                iterator.remove();
            }
        }
        Collections.sort(explainList, new Comparator<FieldAttrEntity>() {
            @Override
            public int compare(FieldAttrEntity o1, FieldAttrEntity o2) {
                //降序
                return o2.getSort() - o1.getSort();
            }
        });
    }

    /**
     * 批量添加分组
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param menuInitDTO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuGroupAddBatchVO
     * @throws XbbException
     */
    private MenuGroupAddBatchVO groupAddBatch(MenuInitDTO menuInitDTO) throws XbbException {
        MenuGroupAddBatchVO menuGroupAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            MenuGroupAddBatchDTO menuGroupAddBatchDTO = new MenuGroupAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, menuGroupAddBatchDTO);
            menuGroupAddBatchDTO.setAppId(appId);
            List<MenuGroupAddDTO> groupMenuList = new ArrayList<>();
            for(CRMMenuEnum crmMenuEnum: CRMMenuEnum.values()){
                if(StringUtil.isEmpty(crmMenuEnum.getParent())){
                    MenuGroupAddDTO crmMenuGroupAddDTO = new MenuGroupAddDTO();
                    BeanUtil.copyProperties(menuInitDTO, crmMenuGroupAddDTO);
                    crmMenuGroupAddDTO.setParentId(0L);
                    crmMenuGroupAddDTO.setAppId(appId);
                    crmMenuGroupAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    crmMenuGroupAddDTO.setAlias(crmMenuEnum.getAlias());
                    crmMenuGroupAddDTO.setName(crmMenuEnum.getName());
                    AccessLinkEnum accessLinkEnum = crmMenuEnum.getAccessLinkEnum();
                    crmMenuGroupAddDTO.setIcon(accessLinkEnum.getIcon());
                    crmMenuGroupAddDTO.setColor(accessLinkEnum.getColor());
                    crmMenuGroupAddDTO.setUrl(accessLinkEnum.getUrl());
                    crmMenuGroupAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                    crmMenuGroupAddDTO.setType(crmMenuEnum.getType());
                    groupMenuList.add(crmMenuGroupAddDTO);
                }
            }
            menuGroupAddBatchDTO.setMenuList(groupMenuList);
            menuGroupAddBatchVO = paasMenuService.addBatchGroupMenu(menuGroupAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.groupAddBatch批量添加分组出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuGroupAddBatchVO;
    }

    /**
     * 批量添加表单
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param menuInitDTO
     * @param menuGroupAddBatchVO
     * @return com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO
     * @throws XbbException
     */
    private MenuFormAddBatchVO formAddBatch(MenuInitDTO menuInitDTO, MenuGroupAddBatchVO menuGroupAddBatchVO) throws XbbException {
        MenuFormAddBatchVO menuFormAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            Map<String, PaasMenuEntity> menuMap = new HashMap<>(menuGroupAddBatchVO.getMenuList().size());
            menuGroupAddBatchVO.getMenuList().forEach((item)->{
                menuMap.put(item.getAlias(), item);
            });
            MenuFormAddBatchDTO crmFormAddBatchDTO = new MenuFormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, crmFormAddBatchDTO);
            crmFormAddBatchDTO.setAppId(appId);
            List<MenuFormAddDTO> crmFormMenuList = new ArrayList<>();
            for(CRMMenuEnum crmMenuEnum: CRMMenuEnum.values()){
                if(StringUtil.isEmpty(crmMenuEnum.getParent())){
                    // 踢掉分组
                    continue;
                }
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setAppId(appId);
                if(StringUtil.isEmpty(crmMenuEnum.getParent())){
                    menuFormAddDTO.setParentId(0L);
                }else{
                    menuFormAddDTO.setParentId(menuMap.get(crmMenuEnum.getParent()).getId());
                }
                menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                menuFormAddDTO.setAlias(crmMenuEnum.getAlias());
                menuFormAddDTO.setName(crmMenuEnum.getName());
                AccessLinkEnum accessLinkEnum = crmMenuEnum.getAccessLinkEnum();
                menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
                menuFormAddDTO.setColor(accessLinkEnum.getColor());
                menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
                menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                menuFormAddDTO.setType(crmMenuEnum.getType());
                crmFormMenuList.add(menuFormAddDTO);
            }
            crmFormAddBatchDTO.setMenuList(crmFormMenuList);
            menuFormAddBatchVO = paasMenuService.addBatchFormMenu(crmFormAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formAddBatch批量添加表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuFormAddBatchVO;
    }

    /**
     * 根据菜单获取表单列表
     * @author 吴峰
     * @date 2019/1/24 18:43
     * @param formList 表单列表
     * @param menuList 菜单列表
     * @return 返回需要插入的表单列表
     * @throws XbbException 业务异常
     */
    public List<FormEntityAddDTO> getFormList(List<FormEntityAddDTO> formList, List<PaasMenuEntity> menuList) throws XbbException{
        try {
            for (PaasMenuEntity item : menuList) {
                FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
                BeanUtil.copyProperties(item, formEntityAddDTO);
                CRMMenuEnum crmMenuEnum = CRMMenuEnum.getByAlias(item.getAlias());
                if (Objects.isNull(crmMenuEnum)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                }
                //如果是知识库菜单,无表单
                if (Objects.equals(item.getAlias(), CRMMenuEnum.KNOWLEDGE_BASE.getAlias())) {
                    continue;
                }
                // CRM用分组的alias获取业务
                // 排除客户和机会下子菜单，排除资金管理和签到，排除发票和回款
                boolean result = StringUtil.isNotEmpty(crmMenuEnum.getParent())
                        || CRMMenuEnum.SIGN_IN.getAlias().equals(item.getAlias());
                if(result) {
                    continue;
                }
                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), crmMenuEnum.getCode())) {
                    formEntityAddDTO.setName(I18nMessageUtil.getMessage(BusinessConstant.COMPANY_CUSTOMER_NAME));
                }
                formEntityAddDTO.setBusinessType(crmMenuEnum.getCode());
                formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                formEntityAddDTO.setLabels(getAppDefaultLabel(crmMenuEnum.getCode()));
                formEntityAddDTO.setCustomTitle(getAppDefaultTitle(crmMenuEnum.getCode()));
                formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(crmMenuEnum.getCode()));
                formEntityAddDTO.setBusinessRules("0");
                if(item.getParentId() == 0) {
                    formEntityAddDTO.setMenuId(item.getId());
                }else{
                    // 如果为子项，则menuId为分组的id
                    formEntityAddDTO.setMenuId(item.getParentId());
                }
                // 工作报告含有日报，周报，月报，需要插入三张表，对应菜单为工作报告
                if(CRMMenuEnum.WORK_REPORT.getAlias().equals(item.getAlias())){
                    getWorkReportList(item, formList);
                }else{
                    formList.add(formEntityAddDTO);
                }
                getPersonalCustomer(item, formList);
            }
        }catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.getFormList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formList;
    }

    /**
     * 新建个人客户表单
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param item 仅为客户的实体
     * @param formList 需要插入的表单
     * @return 含有个人客户的表单列表
     */
    private List<FormEntityAddDTO> getPersonalCustomer(PaasMenuEntity item, List<FormEntityAddDTO> formList){
        if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getAlias(), item.getAlias())) {
            FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
            BeanUtil.copyProperties(item, formEntityAddDTO);
            formEntityAddDTO.setName(I18nMessageUtil.getMessage(BusinessConstant.PERSONAL_CUSTOMER_NAME));
            formEntityAddDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formEntityAddDTO.setLabels(getAppDefaultLabel(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
            formEntityAddDTO.setCustomTitle(getAppDefaultTitle(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
            formEntityAddDTO.setSummaryEntity(getAppDefaultSummary(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
            formEntityAddDTO.setMenuId(item.getId());
            formEntityAddDTO.setEnable(0);
            formList.add(formEntityAddDTO);
        }
        return formList;
    }

    /**
     * 获取日报，周报，月报
     * @author 吴峰
     * @date 2019/1/24 18:44
     * @param item 仅为工作报告的实体
     * @param formList 需要插入的表单
     * @return 含有日报周报月报的表单列表
     */
    private List<FormEntityAddDTO> getWorkReportList(PaasMenuEntity item, List<FormEntityAddDTO> formList){
        for(WorkReportEnum workReportEnum: WorkReportEnum.values()) {
            FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
            BeanUtil.copyProperties(item, formEntityAddDTO);
            formEntityAddDTO.setName(workReportEnum.getName());
            formEntityAddDTO.setBusinessType(workReportEnum.getCode());
            formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formEntityAddDTO.setMenuId(item.getId());
            formList.add(formEntityAddDTO);
        }
        return formList;
    }

    /**
     * 公司钉钉待办配置
     * @param corpid 公司id
     * @author xingxing.xiao
     * @date 2019/11/28 16:13
     */
    private void dingtalkWorkrecordConfig(String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("configAlias", CompanyConfigEnum.DINGTALK_WORKRECORD.getAlias());
        Integer count = companyConfigModel.getEntitysCount(param);
        if (count < 1) {
            // 不存在就插入
            companyConfigService.insertCompanyWorkrecordConfig(corpid, 1);
        }
    }

    /**
     * CRM简化版-菜单初始化
     * @param menuInitDTO
     * @param mirrorObj 镜像配置
     * @author xingxing.xiao
     * @date 2019/11/27 21:11
     */
    public MenuInitVO initSimpleMenu(MenuInitDTO menuInitDTO, JSONObject mirrorObj) throws XbbException {
        MenuInitVO menuInitVO = new MenuInitVO();
        try {
            JSONObject menuObj = mirrorObj.getJSONObject(MirrorModuleEnum.MENU.getAlias());
            JSONArray crmMenu = menuObj.getJSONArray(SystemAppMenuEnum.CRM.getAlias());
            JSONObject formObj = mirrorObj.getJSONObject(MirrorModuleEnum.FORM.getAlias());
            JSONArray crmForm = formObj.getJSONArray(SystemAppMenuEnum.CRM.getAlias());
            JSONObject fieldObj = mirrorObj.getJSONObject(MirrorModuleEnum.FIELD.getAlias());

            Long appId = menuInitDTO.getAppMap().get(SystemAppMenuEnum.CRM.getAlias()).getId();
            menuInitDTO.setAppId(appId);

            // 1. 插入菜单分组(父菜单)
            MenuGroupAddBatchVO crmGroupAddBatchVO = groupSimpleAddBatch(menuInitDTO, crmMenu);
            if(Objects.isNull(crmGroupAddBatchVO)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 2. 插入除分组外对应的菜单(子菜单)
            MenuFormAddBatchVO menuFormAddBatchVO = formSimpleAddBatch(menuInitDTO, crmGroupAddBatchVO, crmMenu);
            if (Objects.isNull(menuFormAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 3. 插入菜单对应的表单
            FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formAddBatchDTO);
            List<PaasMenuEntity> menuList = new ArrayList<>();
            menuList.addAll(crmGroupAddBatchVO.getMenuList());
            menuList.addAll(menuFormAddBatchVO.getMenuList());
            List<FormEntityAddDTO> formList = new ArrayList<>();
            getSimpleFormList(formList, menuList, crmForm);
            // 跟进记录的form - 合同业绩分配(特殊)
            setContractPerformance(menuInitDTO.getAppId(), formList, menuInitDTO.getCorpid(), menuInitDTO.getUserId());
            formAddBatchDTO.setFormList(formList);
            FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
            if (Objects.isNull(formAddBatchVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            // 4. 插入表单对应的字段解释
            formExplainSimpleAddBatch(menuInitDTO, formAddBatchVO, fieldObj);
            menuInitVO.setFormList(formAddBatchVO.getFormList());
            // 新公司初始化时，默认开启钉钉待办(enable = 1)
            dingtalkWorkrecordConfig(menuInitDTO.getCorpid());
            // 插入项目决策信息表单
            setDecisionInfoFormAndExplain(appId, menuInitDTO.getCorpid(), menuInitDTO.getUserId());
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("InitCrmMenuHelp.initSimpleMenu初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuInitVO;
    }

    /**
     * CRM简化版-批量添加分组
     * @param menuInitDTO
     * @param crmMenu
     * @date 2019/11/28 10:37
     */
    private MenuGroupAddBatchVO groupSimpleAddBatch(MenuInitDTO menuInitDTO, JSONArray crmMenu) throws XbbException {
        MenuGroupAddBatchVO menuGroupAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            MenuGroupAddBatchDTO menuGroupAddBatchDTO = new MenuGroupAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, menuGroupAddBatchDTO);
            menuGroupAddBatchDTO.setAppId(appId);
            List<MenuGroupAddDTO> groupMenuList = new ArrayList<>();
            for(CRMMenuEnum crmMenuEnum: CRMMenuEnum.values()){
                if(StringUtil.isEmpty(crmMenuEnum.getParent())){
                    MenuGroupAddDTO crmMenuGroupAddDTO = new MenuGroupAddDTO();
                    BeanUtil.copyProperties(menuInitDTO, crmMenuGroupAddDTO);
                    crmMenuGroupAddDTO.setParentId(0L);
                    crmMenuGroupAddDTO.setAppId(appId);
                    crmMenuGroupAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    crmMenuGroupAddDTO.setAlias(crmMenuEnum.getAlias());
                    crmMenuGroupAddDTO.setName(crmMenuEnum.getName());
                    AccessLinkEnum accessLinkEnum = crmMenuEnum.getAccessLinkEnum();
                    crmMenuGroupAddDTO.setIcon(accessLinkEnum.getIcon());
                    crmMenuGroupAddDTO.setColor(accessLinkEnum.getColor());
                    crmMenuGroupAddDTO.setUrl(accessLinkEnum.getUrl());
                    crmMenuGroupAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                    crmMenuGroupAddDTO.setType(crmMenuEnum.getType());
                    if (!crmMenu.contains(crmMenuEnum.getAlias())) {
                        // 镜像中没有配置的，不开启
                        crmMenuGroupAddDTO.setEnable(BasicConstant.NO_USE);
                    }
                    groupMenuList.add(crmMenuGroupAddDTO);
                }
            }
            menuGroupAddBatchDTO.setMenuList(groupMenuList);
            menuGroupAddBatchVO = paasMenuService.addBatchGroupMenu(menuGroupAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.groupAddBatchSimpleCRM简化版-批量添加分组出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuGroupAddBatchVO;
    }

    /**
     * CRM简化版-批量添加表单
     * @param menuInitDTO
     * @param menuGroupAddBatchVO
     * @param crmMenu
     * @return com.xbongbong.pro.menu.pojo.vo.MenuFormAddBatchVO
     * @throws XbbException
     */
    private MenuFormAddBatchVO formSimpleAddBatch(MenuInitDTO menuInitDTO, MenuGroupAddBatchVO menuGroupAddBatchVO, JSONArray crmMenu) throws XbbException {
        MenuFormAddBatchVO menuFormAddBatchVO;
        try {
            Long appId = menuInitDTO.getAppId();
            Map<String, PaasMenuEntity> menuMap = new HashMap<>(menuGroupAddBatchVO.getMenuList().size());
            menuGroupAddBatchVO.getMenuList().forEach((item)->{
                menuMap.put(item.getAlias(), item);
            });
            MenuFormAddBatchDTO crmFormAddBatchDTO = new MenuFormAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, crmFormAddBatchDTO);
            crmFormAddBatchDTO.setAppId(appId);
            List<MenuFormAddDTO> crmFormMenuList = new ArrayList<>();
            for(CRMMenuEnum crmMenuEnum: CRMMenuEnum.values()){
                if(StringUtil.isEmpty(crmMenuEnum.getParent())){
                    // 踢掉分组
                    continue;
                }
                MenuFormAddDTO menuFormAddDTO = new MenuFormAddDTO();
                BeanUtil.copyProperties(menuInitDTO, menuFormAddDTO);
                menuFormAddDTO.setAppId(appId);
                if(StringUtil.isEmpty(crmMenuEnum.getParent())){
                    menuFormAddDTO.setParentId(0L);
                }else{
                    menuFormAddDTO.setParentId(menuMap.get(crmMenuEnum.getParent()).getId());
                }
                menuFormAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                menuFormAddDTO.setAlias(crmMenuEnum.getAlias());
                menuFormAddDTO.setName(crmMenuEnum.getName());
                AccessLinkEnum accessLinkEnum = crmMenuEnum.getAccessLinkEnum();
                menuFormAddDTO.setIcon(accessLinkEnum.getIcon());
                menuFormAddDTO.setColor(accessLinkEnum.getColor());
                menuFormAddDTO.setUrl(accessLinkEnum.getUrl());
                menuFormAddDTO.setMobileUrl(accessLinkEnum.getMobileUrl());
                menuFormAddDTO.setType(crmMenuEnum.getType());
                if (!crmMenu.contains(crmMenuEnum.getAlias())) {
                    // 镜像中没有配置的，不开启
                    menuFormAddDTO.setEnable(BasicConstant.NO_USE);
                }
                crmFormMenuList.add(menuFormAddDTO);
            }
            crmFormAddBatchDTO.setMenuList(crmFormMenuList);
            menuFormAddBatchVO = paasMenuService.addBatchFormMenu(crmFormAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formAddBatchSimple 批量添加表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return menuFormAddBatchVO;
    }


    /**
     * CRM简化版-生成表单列表
     * @param formList 表单列表
     * @param menuList 菜单列表
     * @param crmForm  表单镜像
     * @return 返回需要插入的表单列表
     * @throws XbbException 业务异常
     */
    public List<FormEntityAddDTO> getSimpleFormList(List<FormEntityAddDTO> formList, List<PaasMenuEntity> menuList, JSONArray crmForm) throws XbbException{
        try {
            for (PaasMenuEntity item : menuList) {
                FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
                BeanUtil.copyProperties(item, formEntityAddDTO);
                CRMMenuEnum crmMenuEnum = CRMMenuEnum.getByAlias(item.getAlias());
                if (Objects.isNull(crmMenuEnum)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.BUSINESS_TYPE_NOT_EXIST);
                }
                // 排除客户和机会下子菜单，排除资金管理和签到，排除发票和回款(也可用 MenuTypeEnum 来判断)
                boolean result = StringUtil.isNotEmpty(crmMenuEnum.getParent())
                        || CRMMenuEnum.SIGN_IN.getAlias().equals(item.getAlias());
                if(result) {
                    continue;
                }
                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), crmMenuEnum.getCode())) {
                    formEntityAddDTO.setName(I18nMessageUtil.getMessage(BusinessConstant.COMPANY_CUSTOMER_NAME));
                }
                formEntityAddDTO.setBusinessType(crmMenuEnum.getCode());
                formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                formEntityAddDTO.setLabels(initMenuHelp.getAppDefaultLabelSimple(crmMenuEnum.getCode()));
                formEntityAddDTO.setCustomTitle(getAppDefaultTitle(crmMenuEnum.getCode()));
                formEntityAddDTO.setSummaryEntity(initMenuHelp.getAppDefaultSummarySimple(crmMenuEnum.getCode()));
                formEntityAddDTO.setBusinessRules("0");
                if(item.getParentId() == 0) {
                    formEntityAddDTO.setMenuId(item.getId());
                }else{
                    // 如果为子项，则menuId为分组的id
                    formEntityAddDTO.setMenuId(item.getParentId());
                }
                // 工作报告含有日报，周报，月报，需要插入三张表，对应菜单为工作报告
                if(CRMMenuEnum.WORK_REPORT.getAlias().equals(item.getAlias())){
                    // 表单镜像中只存日报，周报，月报
                    getSimpleWorkReportList(item, formList, crmForm);
                }else{
                    if (!crmForm.contains(crmMenuEnum.getAlias())) {
                        // 镜像中没有配置的，不开启
                        formEntityAddDTO.setEnable(BasicConstant.NO_USE);
                    }
                    formList.add(formEntityAddDTO);
                }
                getPersonalCustomer(item, formList);
            }
        }catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.getSimpleFormList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formList;
    }

    /**
     * CRM简化版-获取日报，周报，月报
     * @param item 仅为工作报告的实体
     * @param formList 需要插入的表单
     * @param crmForm 表单镜像
     * @return 含有日报周报月报的表单列表
     */
    private List<FormEntityAddDTO> getSimpleWorkReportList(PaasMenuEntity item, List<FormEntityAddDTO> formList, JSONArray crmForm){
        for(WorkReportEnum workReportEnum: WorkReportEnum.values()) {
            FormEntityAddDTO formEntityAddDTO = new FormEntityAddDTO();
            BeanUtil.copyProperties(item, formEntityAddDTO);
            formEntityAddDTO.setName(workReportEnum.getName());
            formEntityAddDTO.setBusinessType(workReportEnum.getCode());
            formEntityAddDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formEntityAddDTO.setMenuId(item.getId());
            if (!crmForm.contains(workReportEnum.getAlias())) {
                // 镜像中没有配置的，不开启
                formEntityAddDTO.setEnable(0);
            }
            formList.add(formEntityAddDTO);
        }
        return formList;
    }

    /**
     * CRM简化版-添加表单字段解释
     * @param menuInitDTO
     * @param formAddBatchVO
     * @param fieldObj 字段镜像
     * @author xingxing.xiao
     * @date 2019/11/28 16:28
     */
    public FormExplainAddBatchVO formExplainSimpleAddBatch(MenuInitDTO menuInitDTO, FormAddBatchVO formAddBatchVO, JSONObject fieldObj) throws XbbException {
        FormExplainAddBatchVO formExplainAddBatchVO;
        try {
            FormExplainAddBatchDTO formExplainAddBatchDTO = new FormExplainAddBatchDTO();
            BeanUtil.copyProperties(menuInitDTO, formExplainAddBatchDTO);
            List<FormExplainAddDTO> formExplainList = new ArrayList<>();
            FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(menuInitDTO.getCorpid());
            for (PaasFormEntity item : formAddBatchVO.getFormList()) {
                // 过滤掉bi的一些表单
                BIProductEnum biProductEnum = BIProductEnum.getByCode(item.getBusinessType());
                if (Objects.nonNull(biProductEnum) ||
                        Objects.equals(item.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                    continue;
                }
                FormExplainAddDTO formExplainAddDTO = new FormExplainAddDTO();
                BeanUtil.copyProperties(item, formExplainAddDTO);
                formExplainAddDTO.setFormId(item.getId());
                String alias = XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias();
                CRMMenuEnum crmMenuEnum = CRMMenuEnum.getByAlias(alias);
                // 获取表单对应的字段镜像
                JSONArray fieldArray = fieldObj.getJSONArray(alias);
                if(Objects.nonNull(crmMenuEnum)) {
                    List<FieldAttrEntity> explainList;
                    if(StringUtil.isNotEmpty(crmMenuEnum.getParent())){
                        explainList = InitExplainsHelper.initSimpleFieldAttrEntity(crmMenuEnum.getParent(), fieldArray, menuInitDTO.getProductForm(),fundSetTransitionPojo);
                    } else {
                        explainList = InitExplainsHelper.initSimpleFieldAttrEntity(alias, fieldArray, menuInitDTO.getProductForm(),fundSetTransitionPojo);
                    }
                    // 企业客户和个人客户做特殊处理，会砍掉一些字段
                    if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), item.getBusinessType())
                            && I18nMessageUtil.getMessage(BusinessConstant.COMPANY_CUSTOMER_NAME).equals(item.getName())) {
                        removeCompanyCustomerField(explainList);
                    } else if ((Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), item.getBusinessType()) && I18nMessageUtil.getMessage(BusinessConstant.PERSONAL_CUSTOMER_NAME).equals(item.getName()))) {
                        removePersonalCustomerField(explainList);
                    }
                    formExplainAddDTO.setFormList(explainList);
                } else {
                    // 工作报告(此处比较特殊，因为工作报告存的是日报、周报、月报，所以匹配不上的话就是工作报告)
                    WorkReportEnum workReportEnum = WorkReportEnum.getByCode(item.getBusinessType());
                    formExplainAddDTO.setFormList(InitExplainsHelper.initFieldAttrEntity(workReportEnum.getAlias(), menuInitDTO.getProductForm(), fundSetTransitionPojo, 0));
                }
                // 默认启用，防止不启用的菜单覆盖
                formExplainAddDTO.setEnable(1);
                formExplainList.add(formExplainAddDTO);
            }
            formExplainAddBatchDTO.setFormExplainList(formExplainList);
            formExplainAddBatchVO = paasFormExplainService.addBatch(formExplainAddBatchDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.formExplainSimpleAddBatch批量添加表单解释信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formExplainAddBatchVO;
    }

    /**
     * 初始化，为公司saas模块增加默认打印模板
     * @param  corpid
     * @param  appId
     * @param formList 表单列表
     * @param appAlias 应用alias
     */
    private void rollBackToDefaultPrintTemplates(String corpid,Long appId, List<PaasFormEntity> formList, String appAlias,List<Long> delFormIds) throws XbbException {
        try {
            List<PrintTemplateTypeEnum> printTemplateTypeList = PrintTemplateTypeEnum.getAllEnums();
            List<Integer> businessTypeList = new ArrayList<>();
            for (PrintTemplateTypeEnum printTemplateTypeEnum : printTemplateTypeList) {
                if (printTemplateTypeEnum.getApp().equals(appAlias)) {
                    businessTypeList.add(printTemplateTypeEnum.getCode());
                }
            }
            HashSet<Integer> business = new HashSet<>();
            HashSet<Long> selectFormIds = new HashSet<>();
            formList.forEach(item->{
                business.add(item.getBusinessType());
                selectFormIds.add(item.getId());
            });
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("columns", " id , name");
            param.put("corpid", corpid);
            param.put("appId", appId);
            param.put("formIdIn", selectFormIds);
            param.put("del", DelEnum.NORMAL.getDel());
            List<Long> delIds = new ArrayList<>();
            List<PaasPrintTemplateEntity> paasPrintTemplateEntityList = paasPrintTemplateDao.findEntitys(param);
            for (PaasPrintTemplateEntity paasPrintTemplateEntity : paasPrintTemplateEntityList) {
                delIds.add(paasPrintTemplateEntity.getId());
            }
            if (delIds.size()>0) {
                paasPrintTemplateDao.deleteBatch(delIds, corpid);
            }
            // 查询默认打印模板
            param.clear();
            param.put("corpid", "0");
            param.put("del", DelEnum.NORMAL.getDel());
            List<PaasPrintTemplateEntity> defaultList = paasPrintTemplateDao.findEntitys(param);
            if (defaultList.isEmpty()) {
                // 数据库中没有存在默认模板配置
                return;
            }
            Map<Integer, PaasPrintTemplateEntity> defaultTemplateMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasPrintTemplateEntity templateEntity : defaultList) {
                defaultTemplateMap.put(templateEntity.getBusinessType(), templateEntity);
            }
            long now = DateTimeUtil.getInt();
            // HashSet<Integer> business = new HashSet<>();
            List<PaasPrintTemplateEntity> insertList = new ArrayList<>();
            for (PaasFormEntity paasFormEntity : formList) {
                if (business.contains(paasFormEntity.getBusinessType())) {
                    Integer businessType = paasFormEntity.getBusinessType();
                    if (!businessTypeList.contains(businessType)) {
                        // 无打印的业务跳过；
                        continue;
                    }
                    PaasPrintTemplateEntity defaultEntity = defaultTemplateMap.get(businessType);
                    if (defaultEntity == null) {
                        continue;
                    }
                    PaasPrintTemplateEntity paasPrintTemplateEntity = new PaasPrintTemplateEntity();
                    paasPrintTemplateEntity.setName("默认模板");
                    paasPrintTemplateEntity.setCorpid(corpid);
                    paasPrintTemplateEntity.setAppId(paasFormEntity.getAppId());
                    paasPrintTemplateEntity.setMenuId(paasFormEntity.getMenuId());
                    paasPrintTemplateEntity.setFormId(paasFormEntity.getId());
                    paasPrintTemplateEntity.setCreatorId("0");
                    paasPrintTemplateEntity.setAddTime(now);
                    paasPrintTemplateEntity.setEnable(BasicConstant.ONE);
                    paasPrintTemplateEntity.setUpdateTime(now);
                    paasPrintTemplateEntity.setBusinessType(businessType);
                    paasPrintTemplateEntity.setHtml(defaultEntity.getHtml());
                    paasPrintTemplateEntity.setConfigInfo(defaultEntity.getConfigInfo());
                    insertList.add(paasPrintTemplateEntity);
                    business.remove(paasFormEntity.getBusinessType());
                }
            }

            if (insertList.size()>0) {
                paasPrintTemplateDao.insertBatch(insertList);
            }
        } catch (Exception e) {
            LOG.error("InitCrmMenuHelp.menuInit初始化菜单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 初始化竞争对手分析表单和解释
     * date: 2022/8/17 1:49 下午
     * @author yingjf
     * @param appId:
     * @param corpid:
     * @param creatorId:
     */
    public void setCompetitorAnalysisFormAndExplain(Long appId, String corpid, String creatorId) throws XbbException {
        try {
            PaasFormEntity formEntity = paasFormModel.getByBusinessTypeNoEnable(XbbRefTypeEnum.COMPETITOR_ANALYSIS.getCode(), corpid);
            if (Objects.nonNull(formEntity)) {
                return;
            }
            if (Objects.isNull(creatorId)) {
                creatorId = "0";
            }

            long now = DateUtil.getNow();
            formEntity = new PaasFormEntity(corpid, appId, 0L, XbbRefTypeEnum.COMPETITOR_ANALYSIS.getName(), SaasMarkEnum.SAAS.getCode(),
                    XbbRefTypeEnum.COMPETITOR_ANALYSIS.getCode(), BasicConstant.IS_USE, 0, "", 1, 0, 2,
                    "", "", "", "", null, null, "", "",
                    "", "", creatorId, now, now, DelEnum.NORMAL.getDel(), null, 0, DistributorMarkEnum.OTHER.getCode());

            paasFormModel.insert(formEntity);


            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            paasFormExplainEntity.setExplains("[]");
            paasFormExplainEntity.setDel(DelEnum.NORMAL.getDel());
            paasFormExplainEntity.setAddTime(now);
            paasFormExplainEntity.setUpdateTime(now);
            paasFormExplainEntity.setEnable(BasicConstant.ONE);
            paasFormExplainEntity.setBusinessType(formEntity.getBusinessType());
            paasFormExplainEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
            paasFormExplainEntity.setCreatorId(formEntity.getCreatorId());
            paasFormExplainEntity.setFormId(formEntity.getId());
            paasFormExplainEntity.setCorpid(corpid);
            paasFormExplainEntity.setMenuId(formEntity.getMenuId());
            paasFormExplainEntity.setAppId(formEntity.getAppId());
            paasFormExplainEntity.setDistributorMark(DistributorMarkEnum.OTHER.getCode());
            paasFormExplainModel.insert(paasFormExplainEntity);
        }catch (Exception e){
            LOG.error("初始化竞争对手分析出错",e);
        }
    }
}
